import { _decorator, Component, Node } from 'cc';
import { Tween } from 'cc';
import { tween } from 'cc';
import { Vec3 } from 'cc';
import { App } from '../../../App';
import { Ball } from '../Ball';
import { Vec2 } from 'cc';
import UtilTool from '../../../tools/UtilTool';
import { EventConst } from '../../../common/Common';
import { Intersection2D } from 'cc';
import { Rect } from 'cc';
import { desk } from '../../desk';
import { LanguageMgr } from '../../../language/LanguageMgr';
import GameUtils2 from './GameUtils2';
import { BALL_RADIUS, BLACK_BALL, MAX_FORCE, WHITE_BALL } from '../GameManage';
import { TrainPlayBase } from './TrainPlayBase';
import { GameBaseModel } from '../GameBaseModel';
const { ccclass, property } = _decorator;

let DEFAULT_OPEN_FORCE = 200 // 开球时的力度
let DEFAULT_FORCE = 100 // 默认的力度
let FORCE_IN_LINE_RATIO = 0.08 // 成一直线时的力度系数
let DEFAULT_MIN_FORCE = 20 // 最小击球力度

export class GameTrainAI extends TrainPlayBase {

    init(): void {
        super.init();
    }

    // 获取当前球的列表
    getCurBallList() : Node[] {
        let curBallList = []

        App.Model.gameManage.otherBallArr.forEach((ball) => {
            if(ball.active) {
                curBallList.push(ball)
            }
        })

        return curBallList

    }

    onCue() {
        this.gameLogic.cue.showCue(false)

        // 根据球到洞的距离（选择的洞为和白球与目标球成直线夹角最小的洞），来决定击打的力度
        let info = this.getTargetBall()
        let targetBall = info.targetBall
        let isInRoleLine = info.isInRoleLine


        // 击杆动作 angle为球与球之间的角度
        let moveCue = (angle, force)=>{

            UtilTool.printLog("test cue angle", angle)

            tween(this).delay(1).call(() => {
                this.gameLogic.cue.cueMoveAction(angle, force)
            }).start()

        }

        if(targetBall) {

            let whiteBallPos = new Vec2(this.gameLogic.gameView.whiteBall.worldPosition.z, this.gameLogic.gameView.whiteBall.worldPosition.x)
            let targetBallPos = new Vec2(targetBall.worldPosition.z, targetBall.worldPosition.x)
            
            // let angle = UtilTool.subVector2(targetBallPos, whiteBallPos).angle(new Vec2(1, 0)) * 180 / Math.PI // 球出当前杆的角度

            // let angle = this.hitTargetBallAngle(targetBall)

            // 夹角为整数, 需要判断是哪一边的夹角
            // if(targetBallPos.x > whiteBallPos.x) {
            //     angle = -angle
            // }

            let whiteBallWorldPos = this.gameLogic.gameView.whiteBall.worldPosition
            let targetBallWorldPos = targetBall.worldPosition

            let angle = (App.Model.gameView as GameBaseModel).getAngleByWorld(whiteBallWorldPos, targetBallWorldPos)

            let force = this.getUseForce(whiteBallPos, targetBallPos, isInRoleLine)

            UtilTool.printLog("cur test force ", force)

            moveCue(angle, force)

            let number = targetBall.getComponent(Ball).number
            UtilTool.printLog("cur test target ball ", number, angle)

        } else {
            
            let curBallList = this.getCurBallList()
            if(curBallList.length < 15) {
                console.error("cur test no target ball ")
            }

            moveCue(0, DEFAULT_OPEN_FORCE)
        }

    }

    onTestCue() {
        this.gameLogic.cue.showCue(false)

        // 根据球到洞的距离（选择的洞为和白球与目标球成直线夹角最小的洞），来决定击打的力度
        let info = this.getTargetBall()
        let targetBall = info.targetBall
        let isInRoleLine = info.isInRoleLine


        // 击杆动作
        let moveCue = (cueAngle, force)=>{

            tween(this).delay(1).call(() => {
                this.gameLogic.cue.cueMoveAction(cueAngle, force)
            }).start()

        }

        moveCue(0, 350)

    }


    // 击打目标球角度
    /** 策略
        (1) 两球的直线的目标球的中心点上作一条垂直线
        (2) 取该垂直线上左右半径的五个点，分别与白球点成十条直线
        (3) 求出每条直线与圆的两个交点，从而求出重合度, 知道重合度就知道了大概的目标球前进方向的直线与白球的击打方向的夹角
        (4) 从十条直线中取出白球的前进方向与洞与目标球的直线的夹角最接近的直线，从而确认白球的前进向量
     */
    hitTargetBallAngle(targetBall : Node) : number {
        // 与当前白球到目标球的直线，最近的洞为目标终点
        
        let whiteBall = this.gameLogic.gameView.whiteBall
        let whiteBallPos = new Vec2(whiteBall.worldPosition.z, whiteBall.worldPosition.x)
        let targetPos = new Vec2(targetBall.worldPosition.z, targetBall.worldPosition.x)
        let targetLine = UtilTool.subVector2(targetPos, whiteBallPos)
        let radius = targetBall.getComponent(Ball).getSize()/2

        // 查找与白球到目标球的直线反向的最近的洞
        let rolePosList = this.getBallHitRolePosList()
        rolePosList.sort((pos1, pos2)=>{

            let line1 = UtilTool.subVector2(pos1, whiteBallPos)
            let line2 = UtilTool.subVector2(pos2, whiteBallPos)

            let angle1 = targetLine.angle(line1)
            let angle2 = targetLine.angle(line2)

            return angle1 - angle2
        })

        // whiteBall A  targetPos B 击打点 C

        // 洞与目标球的延长线的碰撞点，即为击打点和方向
        let selectRolePos = rolePosList[0]

        let lineAB = GameUtils2.getLineParms(whiteBallPos, targetPos)
        let a = lineAB[0]
        let b = lineAB[1]
        let c = lineAB[2]

        // 过targetPos点作与lineAB垂直的直线
        let lineBP = GameUtils2.getVerticalLine(targetPos, lineAB)
        let a2 = lineBP[0]
        let b2 = lineBP[1]
        let c2 = lineBP[2]

        let yP = -c2 / b2 // x为零的y点
        let P = new Vec2(0, yP)

        let normalizeBP = UtilTool.subVector2(P, targetPos).normalize() // BP的单位向量

        let lineList = [] // 十条直线
        let maxLineNum = 10
        for(let i=0; i<maxLineNum; i++) {

            let addVec2 = new Vec2(0, 0)

            if(i<maxLineNum/2) {
                addVec2 = normalizeBP.clone().multiplyScalar(-(i+1)*radius)
            } else {
                addVec2 = normalizeBP.clone().multiplyScalar((i+1)*radius)
            }

            let endPos = UtilTool.addVector2(targetPos, addVec2)
            let line = GameUtils2.getLineParms(whiteBallPos, endPos)
            lineList.push(line)
        }

        // let 

        // 最优的角度（等于洞到目标球的直线与白球与目标球的直线夹角）
        // let bestAngle = 

        // 先得到重合度，然后就知道了击打角度，如果此时的击打角度和洞与前进方向的夹角相等，则为最优的击打角度

        // 得到该直线的击打角度
        let getLineHitAngle = (lineAC)=>{
            // let a = lineAC[0]
            // let b = lineAC[1]
            // let c = lineAC[2]

            let d = GameUtils2.getPointToLineDistance(targetPos, lineAC)

            let lineV = GameUtils2.getVerticalLine(targetPos, lineAC) 
            let crossPos = GameUtils2.getLineCrossPoint(lineAC, lineV) // 两条直线的交点
            // 两圆相切时，垂直点到白球中心的距离 ? = (radius*2)的平方 - d的平方再开方
            let lenToC = Math.sqrt((radius*2)*(radius*2) - d*d)
            // 求出两圆相切时的白球的中心点
            let normalizeLine = UtilTool.subVector2(whiteBallPos, crossPos).normalize()
            let whiteCenterPos = UtilTool.addVector2(crossPos, normalizeLine.multiplyScalar(lenToC))

            let lenBC = UtilTool.subVector2(whiteCenterPos, targetPos).length()

            UtilTool.printLog("test len", lenBC)

            return whiteCenterPos   
        }                                   

        // 获取两圆相切时的共切点

        

        let hitPos = getLineHitAngle(lineList[0])

        let angle = UtilTool.subVector2(hitPos, whiteBallPos).angle(new Vec2(0, 1)) * 180 / Math.PI // 球出当前杆的角度

        // whiteBall.worldPosition = new Vec3(hitPos.y, -5, hitPos.x)

        return angle

        // return 0 

    }


    hitTargetBallAngle2(targetBall : Node) : number {
        // 与当前白球到目标球的直线，最近的洞为目标终点
        
        let whiteBall = this.gameLogic.gameView.whiteBall
        let whiteBallPos = new Vec2(whiteBall.worldPosition.z, whiteBall.worldPosition.x)
        let targetPos = new Vec2(targetBall.worldPosition.z, targetBall.worldPosition.x)
        let targetLine = UtilTool.subVector2(targetPos, whiteBallPos)
        let radius = targetBall.getComponent(Ball).getSize()/2

        // 查找与白球到目标球的直线反向的最近的洞
        let rolePosList = this.getBallHitRolePosList()
        rolePosList.sort((pos1, pos2)=>{

            let line1 = UtilTool.subVector2(pos1, whiteBallPos)
            let line2 = UtilTool.subVector2(pos2, whiteBallPos)

            let angle1 = targetLine.angle(line1)
            let angle2 = targetLine.angle(line2)

            return angle1 - angle2
        })

        // whiteBall A  targetPos B role C 

        // 洞与目标球的延长线的碰撞点，即为击打点和方向
        // let selectRolePos = rolePosList[0]
        let selectRolePos = rolePosList[3]

        let lineCB = UtilTool.subVector2(selectRolePos, targetPos)

        UtilTool.printLog("lineCB", lineCB.toString())

        let length = lineCB.length() + radius * 2

        // UtilTool.printLog(lineCB.normalize().multiplyScalar(length).toString())

        let hitPos = UtilTool.subVector2(selectRolePos, lineCB.normalize().multiplyScalar(length))
        let angle = UtilTool.subVector2(hitPos, whiteBallPos).angle(new Vec2(0, 1)) * 180 / Math.PI // 球出当前杆的角度

        // angle = -angle

        // angle -= 1

        UtilTool.printLog("hit angle", angle, hitPos.clone().toString(), whiteBallPos.clone().toString())

        // whiteBall.worldPosition = new Vec3(hitPos.y, 0, hitPos.x)
        
        return angle

    }


    posWhiteBall() {

        App.Event.emit(EventConst.POS_WHITE_BALL, false)

        let whiteBallPos = this.getWhiteBallPos()

        UtilTool.printLog("cur test pos white ball ", whiteBallPos.toString())


        this.posBallCtrl.setWhiteBallPos(whiteBallPos)
    }

    // 获取白球摆放位置
    /** 摆球策略
     *  目标球与洞的连接线，并且没有阻挡球，就摆放在这条线上（反向的延长线上）
     */
    getWhiteBallPos() : Vec3 {

        let curBallList = this.getCurBallList()
        let isContact = (pos) => {
            let temp = false
            for(let i=0; i<curBallList.length; i++) {
                let item = curBallList[i]
                let ballPos = new Vec2(item.worldPosition.z, item.worldPosition.x)
                let distanceLength = UtilTool.subVector2(pos, ballPos).length()

                if(distanceLength < BALL_RADIUS * 2) {
                    temp = true
                    break
                }
            }
            return temp
        }
        
        let canPosList = [] // 可以摆放的位置
        this.posBallCtrl.ballPosList.forEach((item) => {
            let pos = new Vec2(item.z, item.x)
            let isContactBall = isContact(pos)
            if(!isContactBall) {
                canPosList.push(pos)
            }
        })

        // 目标球与洞的连接线，并且没有阻挡球
        let rolePosList = this.getBallHitRolePosList()
        let myBallList = this.getMyBeloginBallList()

        // 获取洞的列表，优先选取和目标球最近的洞
        let sortRoleList = (targetBallPos : Vec2) => {
            rolePosList = rolePosList.sort((a, b) => {
                let aDistance = UtilTool.subVector2(targetBallPos, a).length()
                let bDistance = UtilTool.subVector2(targetBallPos, b).length()
                return aDistance - bDistance
            })
        }

        for(let j=0; j<myBallList.length; j++) {
            let targetBallPos = new Vec2(myBallList[j].worldPosition.z, myBallList[j].worldPosition.x)

            let targetNumber = myBallList[j].getComponent(Ball).number

            sortRoleList(targetBallPos)

            for(let k=0; k<rolePosList.length; k++) {
                let rolePos = rolePosList[k]
                
                UtilTool.printLog("cur getWhiteBallPos", j, k, targetNumber)

                let hasBallList = this.getTwoPointLineNearBall(rolePos, targetBallPos)
                if(hasBallList.length == 0) {
                    let pos = this.getOneLineCanPos(targetBallPos, rolePos)
                    if(pos) {
                        return new Vec3(pos.y, 0, pos.x)
                    }
                }
            }

        }

        // 随机一个位置
        let index = Math.floor(Math.random() * canPosList.length)
        let pos = canPosList[index]
        return new Vec3(pos.y, 0, pos.x)
    }
    
    // 获取目标球
    /**  AI找球策略
    * 1：找出白球到每个洞的射线的附近是否有自己的目标球，如果有，就选取
    * 2：当2不成立时，就直接找白球与每个目标球的连线，进行射击目标球，防止犯规
    * 每条射线要求不能有其他球，否则就不选取
    * 击打球时，能否进洞根据原有的cue的画线来判断
    * 放回的目标球，和是否能直线进洞
    **/
    private getTargetBall() : {targetBall: Node, isInRoleLine: boolean} {
        
        let curBallList = this.getCurBallList()
        let rolePosList = this.getBallHitRolePosList()
        let whiteBall = this.gameLogic.gameView.whiteBall
        let whiteBallPos = new Vec2(whiteBall.worldPosition.z, whiteBall.worldPosition.x)

        let beloinMyBallList = curBallList.filter((ball) => {
            let ballNumber = ball.getComponent(Ball).number
            if(this.isBelognMine(ballNumber)) {
                return true
            }
            return false
        })

        // 1:白球与目标球的直线和白球与洞之间的直线，夹角最小和直线直接没有别的球挡着
        for(let i=0; i<rolePosList.length; i++) {
            let rolePos = rolePosList[i]

            // 沿着白球到洞方向，有大于等于2的球挡着就不选取

            let hasBallList = this.getOneLineBall(whiteBallPos, rolePos)
            let whiteBallLine = UtilTool.subVector2(whiteBallPos, rolePos)
            hasBallList = hasBallList.filter((ball) => { // 与洞口同一条直线上的球

                let ballPos = new Vec2(ball.worldPosition.z, ball.worldPosition.x)
                let ballLine = UtilTool.subVector2(ballPos, rolePos)
                let angle = whiteBallLine.angle(ballLine) * 180 / Math.PI


                UtilTool.printLog("cur angle", angle)
                if(angle < 1) { // 夹角小于0.2度的范围上
                    return true
                }
                return false
            })

            if(hasBallList.length >= 2) {
                continue
            }
            // 不是自己的球，就不选取
            if(hasBallList.length == 1) {
                let ballNumber = hasBallList[0].getComponent(Ball).number
                if(!this.isBelognMine(ballNumber)) {
                    continue
                } else {
                    return {targetBall: hasBallList[0], isInRoleLine: true}
                }
            }
            
        }

        // 2: 直接选取白球与目标球之间没有别的球挡着的目标球
        for(let i=0; i<beloinMyBallList.length; i++) {
            let targetBall = beloinMyBallList[i]
            let targetBallPos = new Vec2(targetBall.worldPosition.z, targetBall.worldPosition.x)

            let hasBallList = this.getTwoPointOnLineBall(whiteBallPos, targetBallPos)
            if(hasBallList.length == 0) {
                return {targetBall: targetBall, isInRoleLine: false}
            }
        }


        // 没有分球时，选择一个随机的球，除了白球和黑球
        let selectList = []
        curBallList.forEach((ball)=>{
            let number = ball.getComponent(Ball).number
            if(number != BLACK_BALL && number != WHITE_BALL) {
                selectList.push(ball)
            }
        })
        let selectIndex = Math.floor(Math.random()*selectList.length)
        let targetBall  = selectList[selectIndex]
        return {targetBall: targetBall, isInRoleLine: false}

    }

    getName() : String {
        return App.language.getLanguageLab(96)
    }

    // 获取两点直线之间附近的球, 不包含两个点上的球
    getTwoPointLineNearBall(p1 : Vec2, p2 : Vec2) : Node[] {
        let lineBallList = this.getOneLineBall(p1, p2)

        let containList = lineBallList.filter((ball) => {
            // 判断是否在两点之间
            let ballPos = new Vec2(ball.worldPosition.z, ball.worldPosition.x)
            let minX = Math.min(p1.x, p2.x) + 0.1
            let maxX = Math.max(p1.x, p2.x) - 0.1
            if(ballPos.x > minX && ballPos.x < maxX) {
                return true
            }
            return false
        })
        return containList

    }

    // 获取两点直线之间的球, 不包含两个点上的球
    getTwoPointOnLineBall(p1 : Vec2, p2 : Vec2) : Node[] {
        let lineBallList = this.getOneLineBall(p1, p2, BALL_RADIUS)

        let containList = lineBallList.filter((ball) => {
            // 判断是否在两点之间
            let ballPos = new Vec2(ball.worldPosition.z, ball.worldPosition.x)
            let minX = Math.min(p1.x, p2.x) + 0.1
            let maxX = Math.max(p1.x, p2.x) - 0.1
            if(ballPos.x > minX && ballPos.x < maxX) {
                return true
            }
            return false
        })
        return containList

    }

    // 获取同一条直线上的球
    /**
    * 判断一条直线是否经过了球(通过判断圆心到直线的距离是否小于半径)
    * 公式：|ax0+by0+c|/√(a^2+b^2)
    * p1, p2是直线上的两点
    * rangeLen 误差范围
     */
    getOneLineBall(p1 : Vec2, p2 : Vec2, rangeLen = BALL_RADIUS*2) : Node[] {    
        let curBallList = this.getCurBallList()
        
        let vectorLine : Vec2 = UtilTool.subVector2(p2, p1)


        let line = GameUtils2.getLineParms(p1, p2)
        let a = line[0]
        let b = line[1]
        let c = line[2]
        

        let hasBallList = curBallList.filter((ball) => {

            let ballPos =  new Vec2(ball.worldPosition.z, ball.worldPosition.x)

            let length = Math.abs(a * ballPos.x + b * ballPos.y + c) / Math.sqrt(a * a + b * b)

            // let vectorBall : Vec2 = UtilTool.subVector2(ballPos, p3)
            // let angle = vectorLine.angle(vectorBall) * 180 / Math.PI
            
            // let rangle = 30 // 误差为30
            // if(angle < 30) { // 夹角小于30度的范围上
            //     if(length < rangle) {
            //         return true
            //     }
            // }
            // return false


            if(length < rangeLen) { // 可以接受的误差
                return true
            }
            return false


        })
        return hasBallList
    }

    // 目标球与洞的连接线方向延长线的可以放置的点
    getOneLineCanPos(targetPos, rolePos) : Vec2 {

        let endPos = this.getReverseExtendLinePoint(targetPos, rolePos)

        if(endPos) {
            // 默认取目标球与最大点的中点
            let pos = new Vec2((targetPos.x + endPos.x) / 2, (targetPos.y + endPos.y) / 2)
            if(this.isCanPos(pos)) {
                return pos
            } else {
                let length = UtilTool.subVector2(targetPos, endPos).length()
                let count = 20 // 分成20份，然后取出可以放置的点
                let normalize = UtilTool.subVector2(endPos, targetPos).normalize()
                for(let i=0; i<count; i++) {
                    let x = targetPos.x + normalize.x * (length / count * i)
                    let y = targetPos.y + normalize.y * (length / count * i)
                    let checkPos = new Vec2(x, y)
                    if(this.isCanPos(checkPos)) {
                        return checkPos
                    }
                }
            }
        }

        return null

    }

    getMyBeloginBallList() : Node[] {
        let myBelognList = []

        this.ballList.forEach((ballNumber) => {
            let ball = this.gameLogic.gameView.getBallByNumber(ballNumber)
            myBelognList.push(ball.node)
        })
        return myBelognList
    }

    // 获取力度值
    /**
     * 白球到目标球的延长线到桌壁的距离，来决定击打的力度
     */
    getUseForce(startPos, targetPos, isInRoleLine:boolean) : number {  

        let deskRect : Rect = this.getDeskRect()
        let maxLength = Math.sqrt(deskRect.width * deskRect.width + deskRect.height * deskRect.height)
        let maxForce = MAX_FORCE

        let containPoint = this.getLineRectPoint(startPos, targetPos, deskRect)

        let selectPointList = []
        if(startPos.x > targetPos.x) { // 白球在目标球的右边
            selectPointList = containPoint.filter((item) => {
                return item.x < targetPos.x // 选取目标球左边的交点
            })
        } else { // 白球在目标球的左边
            selectPointList = containPoint.filter((item) => {
                return item.x > targetPos.x
            })
        }
        if(selectPointList.length >= 1) {
            let endPos = selectPointList[0]
            let length = UtilTool.subVector2(startPos, endPos).length()
            let force = Math.floor(maxForce * length / maxLength)

            if(isInRoleLine) {
                force = Math.max(force * FORCE_IN_LINE_RATIO, DEFAULT_MIN_FORCE)
                return force
            } else {
                // 随机一个值（1/3, 1）
                let random = Math.random() * 2 / 3 + 1 / 3
                force = force * random
                force = Math.max(force, DEFAULT_MIN_FORCE)
                return force
            }

        }

        return DEFAULT_FORCE

    }

    // 获取直线与矩形的全部交点
    getLineRectPoint(p1 : Vec2, p2 : Vec2, rect : Rect) {

        // 得到直线方程 ax+by+c=0
        let line = GameUtils2.getLineParms(p1, p2)
        let a = line[0]
        let b = line[1]
        let c = line[2]
        
        let x1 = rect.x
        let x2 = rect.x + rect.width
        let y3 = rect.y
        let y4 = rect.y + rect.height

        // 带入桌子的每个顶点的x或y坐标到直线方程，得出相交的坐标值，然后取出相交的点
        let y1 = -(a * x1 + c) / b
        let y2 = -(a * x2 + c) / b
        let x3 = -(b * y3 + c) / a
        let x4 = -(b * y4 + c) / a

        let pointList = []
        pointList.push(new Vec2(x1, y1))
        pointList.push(new Vec2(x2, y2))
        pointList.push(new Vec2(x3, y3))
        pointList.push(new Vec2(x4, y4))

        // 新建一个大一点的矩形，判断点是否在矩形内
        let rectBig = new Rect(x1-1, y3-1, rect.width+2, rect.height+2)
        let containPoint = pointList.filter((item) => {
            return rectBig.contains(item)
        })

        return containPoint

    }

    // 是否碰到球了
    isCanPos(ballPos : Vec2) : boolean {
        // let curBallList = this.getCurBallList()

        // let isContact = false
        // for(let i=0; i<curBallList.length; i++) {
        //     let itemPos = new Vec2(curBallList[i].worldPosition.z, curBallList[i].worldPosition.x)
        //     let distance = UtilTool.subVector2(ballPos, itemPos).length()
        //     if(distance < BALL_RADIUS * 2) {
        //         isContact = true
        //         break
        //     }
        // }

        // return isContact

        let worldPos = new Vec3(ballPos.y, 0, ballPos.x)
        return this.posBallCtrl.checkPosIsInRange(worldPos)

    }

    // 获取反向延长线的最大点 (延长线的最终点为延长线的球或者桌壁)
    getReverseExtendLinePoint(targetPos:Vec2, rolePos : Vec2) : Vec2 {
        let deskRect : Rect = this.getDeskRect()
        let radius = BALL_RADIUS
        let posRect : Rect = new Rect(deskRect.x + radius, deskRect.y + radius, deskRect.width - radius * 2, deskRect.height - radius * 2)
        let containPoint = this.getLineRectPoint(targetPos, rolePos, posRect)

        // 找出延长线的点
        let ballList = this.getOneLineBall(targetPos, rolePos)
        let ballPosList = ballList.map((item) => {
            return new Vec2(item.worldPosition.z, item.worldPosition.x)
        })
        let checkPosList = ballPosList.concat(containPoint)
        checkPosList = checkPosList.filter((item) => {
            if(targetPos.x > rolePos.x) { // 目标球在洞的右边
                return item.x > targetPos.x
            } else {
                return item.x < targetPos.x
            }
        })

        checkPosList.sort((a, b) => {
            let aDistance = UtilTool.subVector2(targetPos, a).length()
            let bDistance = UtilTool.subVector2(targetPos, b).length()
            return aDistance - bDistance
        })

        if(checkPosList.length == 0) {
            return null
        } else {
            let selectPos = checkPosList[0]
            let line = GameUtils2.getLineParms(targetPos, rolePos)
            // 带入selectPos.x，得到y
            let a = line[0]
            let b = line[1]
            let c = line[2]
            let y = -(a * selectPos.x + c) / b
            return new Vec2(selectPos.x, y)
        }
    }

    // 获取全部洞口的位置
    getBallHitRolePosList() : Vec2[] {

        let deskRect : Rect = this.getDeskRect()
        let minX = deskRect.x
        let maxX = deskRect.x + deskRect.width
        let minY = deskRect.y
        let maxY = deskRect.y + deskRect.height
        let centerY = (minY + maxY) / 2

        let offest = 0

        let rolePosList = []
        rolePosList.push(new Vec2(minX-offest, maxY+offest)) // 左上
        rolePosList.push(new Vec2(maxX+offest, maxY+offest)) // 右上
        rolePosList.push(new Vec2(minX-offest, minY-offest)) // 左下
        rolePosList.push(new Vec2(maxX+offest, minY-offest)) // 右下
        rolePosList.push(new Vec2(minX-offest, centerY)) // 左中
        rolePosList.push(new Vec2(maxX+offest, centerY)) // 右中

        return rolePosList
    }

    getDeskRect() : Rect {
        return this.gameLogic.gameView.desk.getComponent(desk).deskRect
    }

    reset() {
        super.reset()
        Tween.stopAllByTarget(this)
    }

}

